package com.wmh.baseservice.merchant.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.mybatisplus.methods.CommonServiceImpl;
import com.wmh.baseservice.common.redis.config.RedisConfig;
import com.wmh.baseservice.common.redis.utils.RedisUtil;
import com.wmh.baseservice.common.utils.CommUtil;
import com.wmh.baseservice.common.utils.DateFormatTemplate;
import com.wmh.baseservice.common.utils.LogUtil;
import com.wmh.baseservice.merchant.mapper.MerchantGroupGoodsMapper;
import com.wmh.baseservice.merchant.pojo.*;
import com.wmh.baseservice.merchant.pojo.dto.GroupGoodsDTO;
import com.wmh.baseservice.merchant.pojo.vo.GroupGoodsItemPriceVO;
import com.wmh.baseservice.merchant.repository.MerchantGroupGoodsRepository;
import com.wmh.baseservice.merchant.service.*;
import com.wmh.baseservice.skd.pojo.SkdGoodsSpec;
import com.wmh.baseservice.skd.service.SkdGoodsSpecService;
import com.wmh.baseservice.system.pojo.SysChat;
import com.wmh.baseservice.system.pojo.SysMessage;
import com.wmh.baseservice.system.service.SysChatService;
import com.wmh.baseservice.system.service.SysMessageService;
import com.wmh.baseservice.user.mapper.UsGroupGoodsOrderMapper;
import com.wmh.baseservice.user.pojo.UsGroupGoodsOrder;
import com.wmh.baseservice.user.pojo.UsIncomeExpend;
import com.wmh.baseservice.user.pojo.UsInfo;
import com.wmh.baseservice.user.service.UsGroupGoodsOrderService;
import com.wmh.baseservice.user.service.UsIncomeExpendService;
import com.wmh.baseservice.user.service.UsInfoService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wmh generator
 * @since 2022-03-03
 */
@Service
public class MerchantGroupGoodsServiceImpl extends CommonServiceImpl<MerchantGroupGoodsMapper, MerchantGroupGoods> implements MerchantGroupGoodsService {

    @Resource
    private MerchantGroupGoodsPriceService merchantGroupGoodsPriceService;
    @Resource
    private SkdGoodsSpecService merchantSpecService;
    @Resource
    private MerchantGroupGoodsMapper merchantGroupGoodsMapper;
    @Resource
    private MerchantGroupGoodsBuyService merchantGroupGoodsBuyService;
    @Resource
    private MerchantGroupGoodsRepository merchantGroupGoodsRepository;
    @Resource
    private UsGroupGoodsOrderMapper usGroupGoodsOrderMapper;
    @Resource
    private UsInfoService usInfoService;
    @Resource
    private MerchantInfoService merchantInfoService;
    @Resource
    private UsGroupGoodsOrderService usGroupGoodsOrderService;
    @Resource
    private UsIncomeExpendService usIncomeExpendService;
    @Resource
    private MerchantIncomeExpendService merchantIncomeExpendService;
    @Resource
    private SysChatService sysChatService;
    @Resource
    private SysMessageService sysMessageService;
    @Resource
    private RedisUtil redisUtil;


//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void add(MerchantGroupGoods merchantGroupGoods, List<JSONObject> priceArray, String areaList) {
//        if (CommUtil.checkNull(areaList)) {
//            //没有购买区域限制
//            merchantGroupGoods.setHasAreaLimit(1);
//        }
//        if (!save(merchantGroupGoods)) {
//            throw new ServiceException();
//        }
//        //添加团购优惠档次/规格
//        List<MerchantGroupGoodsPrice> merchantGroupGoodsPriceList = new ArrayList<>();
//        List<GroupGoodsItemPriceVO> priceList = new ArrayList<>();
//        priceArray.forEach(item -> {
//            JSONObject object = JSONObject.parseObject(item.toString());
//            GroupGoodsItemPriceVO vo = new GroupGoodsItemPriceVO();
//            if (merchantGroupGoods.getHasSpec() != -1) {
//                //有规格
//                String specName = object.getString("specName");
//                BigDecimal originalPrice = object.getBigDecimal("originalPrice");
//                Integer inventory = object.getInteger("inventory");
//                SkdGoodsSpec skdGoodsSpec = new SkdGoodsSpec().setDescription(specName).setOriginPrice(originalPrice).setInventory(inventory).setType(2).setGoodsId(merchantGroupGoods.getId());
//                if (!merchantSpecService.save(skdGoodsSpec)) {
//                    throw new ServiceException(skdGoodsSpec.toString());
//                }
//                vo.setId(skdGoodsSpec.getId().toString()).setInventory(skdGoodsSpec.getInventory())
//                        .setSpecName(skdGoodsSpec.getDescription()).setOriginalPrice(skdGoodsSpec.getOriginPrice());
//                ArrayList<MerchantGroupGoodsPrice> prices = new ArrayList<>();
//                JSONArray priceGear = object.getJSONArray("priceGear");
//                priceGear.forEach(gear -> {
//                    JSONObject gearObject = JSONObject.parseObject(gear.toString());
//                    Integer successGear = gearObject.getInteger("successGear");
//                    BigDecimal discountPrice = gearObject.getBigDecimal("discountPrice");
//                    MerchantGroupGoodsPrice merchantGroupGoodsPrice = new MerchantGroupGoodsPrice().setGroupGoodsId(merchantGroupGoods.getId()).setDiscountPrice(discountPrice)
//                            .setSuccessGear(successGear).setType(1).setSpecId(skdGoodsSpec.getId());
//                    merchantGroupGoodsPriceList.add(merchantGroupGoodsPrice);
//                    prices.add(merchantGroupGoodsPrice);
//                });
//                vo.setPriceGear(prices);
//                priceList.add(vo);
//            } else {
//                //无规格
//                Integer successGear = object.getInteger("successGear");
//                BigDecimal discountPrice = object.getBigDecimal("discountPrice");
//                MerchantGroupGoodsPrice merchantGroupGoodsPrice = new MerchantGroupGoodsPrice().setGroupGoodsId(merchantGroupGoods.getId()).setDiscountPrice(discountPrice)
//                        .setSuccessGear(successGear).setType(-1);
//                merchantGroupGoodsPriceList.add(merchantGroupGoodsPrice);
//
//            }
//        });
//
//        JSONObject object = new JSONObject();
//
//        object.put("priceList", merchantGroupGoods.getHasSpec() != -1 ?
//                JSONObject.toJSONString(priceList) : JSONObject.toJSONString(merchantGroupGoodsPriceList));
//
//        //如果商家有选择指定购买区域的话添加可购买区域
//        if (CommUtil.checkNull(areaList)) {
//            List<MerchantGroupGoodsBuy> merchantGroupGoodsBuys = new ArrayList<>();
//            String[] split = areaList.split(",");
//            for (String id : split) {
//                MerchantGroupGoodsBuy merchantGroupGoodsBuy = new MerchantGroupGoodsBuy().setGroupGoodsId(merchantGroupGoods.getId()).setAreaId(Long.parseLong(id));
//                merchantGroupGoodsBuys.add(merchantGroupGoodsBuy);
//            }
//            if (!merchantGroupGoodsBuyService.saveBatch(merchantGroupGoodsBuys)) {
//                throw new ServiceException(merchantGroupGoodsBuys.toString());
//            }
//        }
//
//        object.put("areaList", areaList);
//        merchantGroupGoodsMapper.updateById(merchantGroupGoods.setSnapshot(object.toString()));
//
//        if (!merchantGroupGoodsPriceService.saveBatch(merchantGroupGoodsPriceList)) {
//            throw new ServiceException();
//        }
//        setGroupGoodsOverTiming(merchantGroupGoods);
//    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void updateGroupGoods(MerchantGroupGoods merchantGroupGoods, List<JSONObject> priceArray, Integer hasSpec, String areaList) {
//        if (CommUtil.checkNull(areaList)) {
//            //没有购买区域限制
//            merchantGroupGoods.setHasAreaLimit(1);
//        } else {
//            merchantGroupGoods.setHasAreaLimit(-1);
//        }
//        merchantGroupGoods.setHasSpec(hasSpec);
//        //删除原团购价格
//        if (!merchantGroupGoodsPriceService.remove(new QueryWrapper<MerchantGroupGoodsPrice>().eq(MerchantGroupGoodsPrice.GROUP_GOODS_ID, merchantGroupGoods.getId()))) {
//            throw new ServiceException("修改团购商品价格出错");
//        }
//        //删除原可购买区域
//        QueryWrapper<MerchantGroupGoodsBuy> eq = new QueryWrapper<MerchantGroupGoodsBuy>().eq(MerchantGroupGoodsBuy.GROUP_GOODS_ID, merchantGroupGoods.getId());
//        List<MerchantGroupGoodsBuy> rawMerchantGroupGoodsBuys = merchantGroupGoodsBuyService.listForUpdate(eq);
//        if (rawMerchantGroupGoodsBuys.size() != 0) {
//            if (!merchantGroupGoodsBuyService.remove(eq)) {
//                throw new ServiceException("删除购买区域出错");
//            }
//        }
//
//        //删除原规格
//        QueryWrapper<SkdGoodsSpec> specQw = new QueryWrapper<SkdGoodsSpec>().eq(SkdGoodsSpec.GOODS_ID, merchantGroupGoods.getId()).eq(SkdGoodsSpec.TYPE, 2);
//        List<SkdGoodsSpec> merchantSpecs = merchantSpecService.listForUpdate(specQw);
//        if (merchantSpecs.size() != 0) {
//            if (!merchantSpecService.remove(specQw)) {
//                throw new ServiceException("删除规格出错");
//            }
//        }
//        if (!updateById(merchantGroupGoods)) {
//            throw new ServiceException("修改团购商品出错");
//        }
//        //添加团购优惠档次/规格
//        List<MerchantGroupGoodsPrice> merchantGroupGoodsPriceList = new ArrayList<>();
//        List<GroupGoodsItemPriceVO> priceList = new ArrayList<>();
//        priceArray.forEach(item -> {
//            JSONObject object = JSONObject.parseObject(item.toString());
//            GroupGoodsItemPriceVO vo = new GroupGoodsItemPriceVO();
//            if (merchantGroupGoods.getHasSpec() != -1) {
//                //有规格
//                String specName = object.getString("specName");
//                BigDecimal originalPrice = object.getBigDecimal("originalPrice");
//                Integer inventory = object.getInteger("inventory");
//                SkdGoodsSpec merchantSpec = new SkdGoodsSpec().setDescription(specName).setOriginPrice(originalPrice).setInventory(inventory).setType(2).setGoodsId(merchantGroupGoods.getId());
//                if (!merchantSpecService.save(merchantSpec)) {
//                    throw new ServiceException(merchantSpec.toString());
//                }
//                vo.setId(merchantSpec.getId().toString()).setInventory(merchantSpec.getInventory())
//                        .setSpecName(merchantSpec.getDescription()).setOriginalPrice(merchantSpec.getOriginPrice());
//                ArrayList<MerchantGroupGoodsPrice> prices = new ArrayList<>();
//                JSONArray priceGear = object.getJSONArray("priceGear");
//                priceGear.forEach(gear -> {
//                    JSONObject gearObject = JSONObject.parseObject(gear.toString());
//                    Integer successGear = gearObject.getInteger("successGear");
//                    BigDecimal discountPrice = gearObject.getBigDecimal("discountPrice");
//                    MerchantGroupGoodsPrice merchantGroupGoodsPrice = new MerchantGroupGoodsPrice().setGroupGoodsId(merchantGroupGoods.getId()).setDiscountPrice(discountPrice)
//                            .setSuccessGear(successGear).setType(1).setSpecId(merchantSpec.getId());
//                    merchantGroupGoodsPriceList.add(merchantGroupGoodsPrice);
//                    prices.add(merchantGroupGoodsPrice);
//                });
//                vo.setPriceGear(prices);
//                priceList.add(vo);
//            } else {
//                //无规格
//                Integer successGear = object.getInteger("successGear");
//                BigDecimal discountPrice = object.getBigDecimal("discountPrice");
//                MerchantGroupGoodsPrice merchantGroupGoodsPrice = new MerchantGroupGoodsPrice().setGroupGoodsId(merchantGroupGoods.getId()).setDiscountPrice(discountPrice)
//                        .setSuccessGear(successGear).setType(-1);
//                merchantGroupGoodsPriceList.add(merchantGroupGoodsPrice);
//            }
//        });
//
//        JSONObject object = new JSONObject();
//        object.put("priceList", merchantGroupGoods.getHasSpec() != -1 ?
//                JSONObject.toJSONString(priceList) : JSONObject.toJSONString(merchantGroupGoodsPriceList));
//
//        //如果商家有选择指定购买区域的话添加可购买区域
//        if (CommUtil.checkNull(areaList)) {
//            List<MerchantGroupGoodsBuy> merchantGroupGoodsBuys = new ArrayList<>();
//            String[] split = areaList.split(",");
//            for (String id : split) {
//                MerchantGroupGoodsBuy merchantGroupGoodsBuy = new MerchantGroupGoodsBuy().setGroupGoodsId(merchantGroupGoods.getId()).setAreaId(Long.parseLong(id));
//                merchantGroupGoodsBuys.add(merchantGroupGoodsBuy);
//            }
//            if (!merchantGroupGoodsBuyService.saveBatch(merchantGroupGoodsBuys)) {
//                throw new ServiceException(merchantGroupGoodsBuys.toString());
//            }
//        }
//
//        object.put("areaList", areaList);
//        merchantGroupGoodsMapper.updateById(merchantGroupGoods.setSnapshot(object.toString()));
//
//        if (!merchantGroupGoodsPriceService.saveBatch(merchantGroupGoodsPriceList)) {
//            throw new ServiceException();
//        }
//        setGroupGoodsOverTiming(merchantGroupGoods);
//    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void weakUpdateGroupGoods(MerchantGroupGoods item, List<JSONObject> priceArray) {
//        // 判断是否存在优惠规格
//        if (item.getHasSpec() == 1) {
//            JSONObject snapshot = JSONObject.parseObject(item.getSnapshot());
//            List<JSONObject> oldList = JSONArray.parseArray(JSONObject.parseObject(item.getSnapshot()).getString("priceList"), JSONObject.class);
//            if (oldList.size() != priceArray.size() ||
//                    priceArray.stream().anyMatch(e -> e.getLong("id") == null)
//            ) {
//                throw new ServiceException("商品正在拼团中, 不能删除或添加新的规格信息, 只能对库存进行操作.");
//            }
//            oldList.sort((a, b) -> Long.compare(Long.parseLong(b.getString("id")), Long.parseLong(a.getString("id"))));
//            priceArray.sort((a, b) -> Long.compare(Long.parseLong(b.getString("id")), Long.parseLong(a.getString("id"))));
//
//            LogUtil.debug("oldList : {}  len : {}", oldList, oldList.size());
//            LogUtil.debug("priceArray : {} len : {}", priceArray, priceArray.size());
//
//            // JSON : {"originalPrice":1,"specName":"1","id":"251","inventory":11111,"priceGear":[{"specId":251,"groupGoodsId":86,"successGear":123,"discountPrice":1,"type":1}]}
//            for (int i = 0; i < priceArray.size(); i++) {
//                LogUtil.debug("item : {}", priceArray.get(i));
//                LogUtil.debug("priceGear : {}", priceArray.get(i).getJSONArray("priceGear"));
//                Integer inventory = priceArray.get(i).getInteger("inventory");
//                if (inventory != -1) {
//                    boolean match = priceArray.get(i).getJSONArray("priceGear").stream().anyMatch(e -> (((JSONObject) e).getInteger("successGear")) > inventory);
//                    if (match) {
//                        throw new ServiceException("修改商品失败,优惠档位数量不能超过该规格的库存量. 规格名 : " + priceArray.get(i).getString("specName"));
//                    }
//                    // 将新的规格库存 放到 json 中
//                    oldList.get(i).put("inventory", priceArray.get(i).getInteger("inventory"));
//                    boolean result = merchantSpecService.update(new UpdateWrapper<SkdGoodsSpec>()
//                            .eq(SkdGoodsSpec.GOODS_ID, item.getId())
//                            .eq(SkdGoodsSpec.ID, priceArray.get(i).getLong("id"))
//                            .set(SkdGoodsSpec.INVENTORY, priceArray.get(i).getInteger("inventory")));
//                    if (!result) {
//                        throw new ServiceException();
//                    }
//                }
//            }

//            // 重新设置商品快照
//            snapshot.put("priceList", JSONObject.toJSONString(oldList));
//            LogUtil.debug("now-snapshot : {}", snapshot);
//            item.setSnapshot(snapshot.toJSONString());
////            if (!update(new UpdateWrapper<MerchantGroupGoods>()
////                    .eq(MerchantGroupGoods.ID, item.getId())
////                    .set(MerchantGroupGoods.SNAPSHOT, snapshot.toString())
////            )) {
////                throw new ServiceException();
////            }
//        } else if (item.getHasSpec() == -1 && item.getInventory() != -1) {
//            LogUtil.debug("inventory : {}", item.getInventory());
//            List<MerchantGroupGoodsPrice> list = merchantGroupGoodsPriceService.list(
//                    new QueryWrapper<MerchantGroupGoodsPrice>()
//                            .eq(MerchantGroupGoodsPrice.GROUP_GOODS_ID, item.getId())
//            );
//            boolean match = list.stream().anyMatch(e -> e.getSuccessGear() > item.getInventory());
//            if (match) {
//                throw new ServiceException("修改商品失败,优惠档位数量不能超过库存数量");
//            }
//        }
//        if (!updateById(item)) {
//            throw new ServiceException("修改商品失败,系统异常");
//        }
//        if (!update(new UpdateWrapper<MerchantGroupGoods>()
//                .eq(MerchantGroupGoods.ID, item.getId())
//                .set(MerchantGroupGoods.INVENTORY, item.getInventory())//
//        ))
//        {
//        }
//    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void delete(MerchantGroupGoods merchantGroupGoods) {
//        if (isSpellGrouping(merchantGroupGoods.getId())) {
//            throw new ServiceException("该商品正在拼团中,请待拼团结算后删除");
//        }
//        //删除团购商品
//        if (!removeById(merchantGroupGoods.getId())) {
//            throw new ServiceException();
//        }
//        //删除原团购价格
//        if (!merchantGroupGoodsPriceService.remove(new QueryWrapper<MerchantGroupGoodsPrice>().eq(MerchantGroupGoodsPrice.GROUP_GOODS_ID, merchantGroupGoods.getId()))) {
//            throw new ServiceException("修改团购商品价格出错");
//        }
//        //删除原可购买区域
//        QueryWrapper<MerchantGroupGoodsBuy> eq = new QueryWrapper<MerchantGroupGoodsBuy>().eq(MerchantGroupGoodsBuy.GROUP_GOODS_ID, merchantGroupGoods.getId());
//        List<MerchantGroupGoodsBuy> merchantGroupGoodsBuys = merchantGroupGoodsBuyService.listForUpdate(eq);
//        if (merchantGroupGoodsBuys.size() != 0 && (!merchantGroupGoodsBuyService.remove(eq))) {
//                throw new ServiceException("删除购买区域出错");
//
//        }
//
//        //删除原规格
//        QueryWrapper<SkdGoodsSpec> specQw = new QueryWrapper<SkdGoodsSpec>().eq(SkdGoodsSpec.GOODS_ID, merchantGroupGoods.getId()).eq(SkdGoodsSpec.TYPE, 2);
//        List<SkdGoodsSpec> merchantSpecs = merchantSpecService.listForUpdate(specQw);
//        if (merchantSpecs.size() != 0 && (!merchantSpecService.remove(specQw))) {
//                throw new ServiceException("删除规格出错");
//
//        }
//        merchantGroupGoodsRepository.rmTiming(merchantGroupGoods.getId());
//    }

    @Override
    public IPage<MerchantGroupGoods> searchList(Page<MerchantGroupGoods> page, Map<String, Object> map) {
        return merchantGroupGoodsMapper.searchList(page, map);
    }

    @Override
    public void setGroupGoodsOverTiming(MerchantGroupGoods merchantGroupGoods) {
        merchantGroupGoodsRepository.setTiming(merchantGroupGoods.getId(),
                DateFormatTemplate.paresDate(merchantGroupGoods.getEndTime()));
    }

    @Override
    public void removeGroupGoodsOverTiming(MerchantGroupGoods merchantGroupGoods) {
        merchantGroupGoodsRepository.rmTiming(merchantGroupGoods.getId());
    }

    @Override
    public boolean isSpellGrouping(Long id) {
        MerchantGroupGoods result = getOneForUpdate(new QueryWrapper<MerchantGroupGoods>()
                .eq(MerchantGroupGoods.ID, id)
                .ge(MerchantGroupGoods.END_TIME, LocalDateTime.now(DateFormatTemplate.ZONE_SHANGHAI)
                        .format(DateTimeFormatter.ofPattern(DateFormatTemplate.GROUP_GOODS_WRITE)))
                .eq(MerchantGroupGoods.STATUS, 0));
        return CommUtil.checkNull(result);
    }

    @Override
    public void isPreferentialOverweight(Integer hasSpec, Integer originalInventory, BigDecimal originalPrice, List<JSONObject> priceArr) {
        if (hasSpec == -1) {
            priceArr.sort((o1, o2) -> {
                Integer n2 = o2.getInteger("successGear");
                Integer n1 = o1.getInteger("successGear");
                return n2 - n1;
            });

            // 最高优惠档位需求数量 不能 大于 当前库存
            if (originalInventory != -1 && priceArr.get(0).getInteger("successGear").compareTo(originalInventory) > 0) {
                throw new ServiceException("请检查无规格购买参数信息, 满足优惠档位商品数量 不能 大于 该商品的库存");
            }
            // 最低优惠单位 商品单价 不能 大于等于 团购商品原价
            if (priceArr.get(priceArr.size() - 1).getBigDecimal("discountPrice").compareTo(originalPrice) > -1) {
                throw new ServiceException("请检查无规格购买参数信息, 商品优惠单价 不能 大于或等于 该商品的原价");
            }
            if (priceArr.size() > 1) {
                // 多个档位, 高需量档位 优惠价格 不能低于 低需量档位 优惠价格 并且都不能高于原价
                for (int now = 0, last = 1; now < priceArr.size() && last < priceArr.size(); now++, last++) {
                    // 得到当前价格
                    BigDecimal nowPrice = priceArr.get(now).getBigDecimal("discountPrice");
                    // 得到上一档位价格
                    BigDecimal lastPrice = priceArr.get(last).getBigDecimal("discountPrice");
                    if (nowPrice.compareTo(lastPrice) > 0) {
                        throw new ServiceException("请检查无规格购买参数信息, 高优惠档位商品优惠单价 不得大于 比起低的档位优惠单价");
                    }
                }
            }

        } else if (hasSpec == 1) {
            for (JSONObject item : priceArr) {

                // 得到库存
                Integer num = item.getInteger("inventory");

                // 得到规格列表
                List<JSONObject> priceGear = JSONArray.parseArray(item.getString("priceGear"), JSONObject.class);
                // 按需要满足的数量倒排
                priceGear.sort((a, b) -> b.getInteger("successGear") - a.getInteger("successGear"));

                // 判断当前规格最高优惠挡位需求量 是否超过了当前规格的库存
                if (num != -1 && priceGear.get(0).getInteger("successGear") > num) {
                    throw new ServiceException("请检查规格 : " + item.getString("specName") + " 参数 达到优惠挡位的所需量 不能高于该规格库存");
                }

                // 得到原价
                BigDecimal oldPrice = item.getBigDecimal("originalPrice");

                // 最低优惠挡位 单价 不能 大于或等于 该规格原价
                if (priceGear.get(priceGear.size() - 1).getBigDecimal("discountPrice").compareTo(oldPrice) > -1) {
                    throw new ServiceException("请检查规格 : " + item.getString("specName") + " 参数 商品优惠单价 不能 大于或等于 该规格原价");
                }

                if (priceGear.size() > 1) {
                    // 多个档位, 高需量档位 优惠价格 不能低于 低需量档位 优惠价格 并且都不能高于原价
                    for (int now = 0, last = 1; now < priceGear.size() && last < priceGear.size(); now++, last++) {
                        // 得到当前价格
                        BigDecimal nowPrice = priceGear.get(now).getBigDecimal("discountPrice");
                        // 得到上一档位价格
                        BigDecimal lastPrice = priceGear.get(last).getBigDecimal("discountPrice");
                        if (nowPrice.compareTo(lastPrice) > 0) {
                            throw new ServiceException("请检查规格 : " + item.getString("specName") + " 高优惠档位商品优惠单价 不得大于 比起低的档位优惠单价");
                        }
                    }
                }
            }
        }
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void settlementGroupGoodsCashBack(Long bgId) {
//        // 得到要结算的商品
//        MerchantGroupGoods goods = getOneForUpdate(
//                new QueryWrapper<MerchantGroupGoods>()
//                        .eq(MerchantGroupGoods.ID, bgId));
//        if (!CommUtil.checkNull(goods)) {
//            LogUtil.warn("团购结算异常 -> 不存在的商品 id: {}", bgId);
//            return;
//        }
//
//        LocalDateTime end = DateFormatTemplate.paresDate(goods.getEndTime());
//        LocalDateTime now = LocalDateTime.now(DateFormatTemplate.ZONE_SHANGHAI).plusMinutes(1);
//        if (!end.isBefore(now)) {
//            LogUtil.warn("团购结算异常 -> 当前时间 : {} , 该商品没有达到结算时间将重建缓存 : {}", now.format(DateTimeFormatter.ofPattern(DateFormatTemplate.GROUP_GOODS_WRITE)), goods);
//            // 重设结算时间
//            setGroupGoodsOverTiming(goods);
//            return;
//        }
//
//        // 获得当前彼此团购商品订单 待发货 待收货 待提货 根据购买时间 降序排序
//        List<UsGroupGoodsOrder> orderList = usGroupGoodsOrderMapper.selectList(
//                new QueryWrapper<UsGroupGoodsOrder>()
//                        .eq(UsGroupGoodsOrder.MERCHANT_ID, goods.getMerchantId())
//                        .eq(UsGroupGoodsOrder.GROUP_GOODS_ID, goods.getId())
//                        .eq(UsGroupGoodsOrder.BATCH, goods.getBatchNum())
//                        .in(UsGroupGoodsOrder.STATUS, 1, 2, 3, 4, 5)
//                        .orderByAsc(UsGroupGoodsOrder.PAY_TIME)
//        );
//
//        goods.setStatus(-1);
//
//
//        if (orderList.size() == 0) {
//            LogUtil.warn("团购结算 -> 当前商品没有订单 : {}", goods);
//        }
//
//        // 开始结算业务
//        Map<String, Object> map = new HashMap<>();
//        // 指定当前商品批次
//        map.put("batch", goods.getBatchNum());
//        // 指定当前订单团购 id
//        map.put("groupGoodsId", goods.getId());
//
//        /* 规格id 与 当前团购商品某规格总购买数量达到的最大优惠档位映射
//         *  k: 规格 id v : 当前规格已达到的最大优惠档位
//         * */
//        HashMap<Long, MerchantGroupGoodsPrice> specMp = new HashMap<>();
//        /*
//         * 需要返现的数量映射
//         * 例 : 原价 100
//         * 满10件 90元
//         * 满20件 80元
//         * 满30件 70元
//         * 满40件 60元
//         * 此时用户 1 购买了 10件每件90元 共 900元
//         * 用户 2 购买了 10 件达到了 20件每件80元 则为 800 元, 此时用户1返现 900 - 80 * 10 = 100元
//         * 用户 3 购买了 20 件达到了 40件每件60元 则为 1200 元, 此时用户2返现 800 - 60 * 10 = 200元, 用户1 返现 900 - 60 * 10 = 300元
//         * k: 规格 id id v : 需要返现的数量
//         * */
//        HashMap<Long, Integer> specBackMp = new HashMap<>();
//
//        /* 商品id 与 当前团购商品某规格总购买数量达到的最大优惠档位映射
//         *  k: 团购商品id id v : 当前商品已达到的最大优惠档位
//         * */
//        HashMap<Long, MerchantGroupGoodsPrice> noSpecMp = new HashMap<>();
//
//        /* 需要返现的数量映射
//         *  k: 团购商品id id v : 当前商品已达到的最大优惠档位
//         * */
//        HashMap<Long, Integer> noSpecBackMp = new HashMap<>();
//
//        orderList.forEach(order -> {
//
//            List<UsIncomeExpend> usIncomeExpendList = new ArrayList<>();
//            List<MerchantIncomeExpend> merchantIncomeExpendList = new ArrayList<>();
//
//            // 返现金额
//            BigDecimal backMoney = null;
//
//            // 查询用户和商家，给后面返还余额和商家余额扣减用
//            UsInfo usInfo = usInfoService.getByIdForUpdate(order.getUsId());
//            MerchantInfo merchantInfo = merchantInfoService.getByIdForUpdate(order.getMerchantId());
//
//
//            /* 开始计算返现 */
//
//            // 如果订单有规格
//            if (CommUtil.checkNull(order.getSpecId())) {
//                map.put("specId", order.getSpecId());
//
//                //获取拼团参数列表 ,
//                List<MerchantGroupGoodsPrice> merchantGroupGoodsPrices = merchantGroupGoodsPriceService.listForUpdate(new QueryWrapper<MerchantGroupGoodsPrice>()
//                        // 下单的商品id
//                        .eq(MerchantGroupGoodsPrice.GROUP_GOODS_ID, order.getGroupGoodsId())
//                        // 下单的规格规格id
//                        .eq(MerchantGroupGoodsPrice.SPEC_ID, order.getSpecId())
//                        // 根据优惠档位 降序排序
//                        .orderByDesc(MerchantGroupGoodsPrice.SUCCESS_GEAR));
//
//                MerchantGroupGoodsPrice maxGears = null;
//                // 如果当前订单选择的规格没有缓存已达到的最大优惠档位就缓存
//                if (!specMp.containsKey(order.getSpecId())) {
//                    // 得到当前批次团购当前规格的所有订单的购买的商品数量之和
//                    int totalCount = usGroupGoodsOrderService.totalCount(map);
//
//                    for (MerchantGroupGoodsPrice item : merchantGroupGoodsPrices) {
//                        // 如果当前规格订单购买重量 >= 也就是满足 优惠档位 则得到该优惠档位  并且减去当前订单的购买数量
//                        if (totalCount >= item.getSuccessGear()) {
//                            maxGears = item;
//                            specMp.put(order.getSpecId(), maxGears);
//                            // 设置需要返现数量为当前满足的最大优惠数量
//                            specBackMp.put(order.getSpecId(), maxGears.getSuccessGear());
//                            break;
//                        }
//                    }
//
//                    // 如果第一次没有得当前最大优惠档位 就表示 选择该规格的订单 没有满足任何优惠档位 直接赋值为 null 避免同规格多次查找
//                    if (maxGears == null) {
//                        specMp.put(order.getSpecId(), null);
//                    }
//                } else {
//                    // 如果有就直接赋值
//                    maxGears = specMp.get(order.getSpecId());
//                }
//
//                // 当前订单规格购买的数量
//                Integer nowByCount = order.getCount();
//
//                // maxGears == null 订单没有满足任何档位 不计算返现金额
//                if (maxGears != null) {
//                    // 如果当前购买的数量 大于或等于 当前需要返现的数量 则表示该订单在付款时已达最优惠档位 则不返现 并且将需要返现的数量 设置为 0
//                    if (nowByCount >= specBackMp.get(order.getSpecId())) {
//                        specBackMp.put(order.getSpecId(), 0);
//                    } else {
//                        // 得到当前订单满足的档位
//                        MerchantGroupGoodsPrice meetGears = null;
//                        for (MerchantGroupGoodsPrice item : merchantGroupGoodsPrices) {
//                            if (nowByCount >= item.getSuccessGear()) {
//                                meetGears = item;
//                                break;
//                            }
//                        }
//                        if (meetGears != null) {
//                            // (当前达到的优惠价格 - 拼单达到的最优惠价格) * 当前订单购买的商品数量
//                            backMoney = meetGears.getDiscountPrice()
//                                    .subtract(maxGears.getDiscountPrice()).multiply(BigDecimal.valueOf(order.getCount()));
//                        } else {
//                            // 查询当前优惠档位的 规格原价
//                            SkdGoodsSpec nowSpec = merchantSpecService.getByIdForUpdate(order.getSpecId());
//                            if (nowSpec == null) {
//                                throw new ServiceException("商品结算失败 -> 没有找到该商品规格 id:" + order.getSpecId());
//                            }
//                            BigDecimal originPrice = nowSpec.getOriginPrice();
//                            // (规格原价 - 拼单达到的最优惠价格) * 当前订单购买数量
//                            backMoney = originPrice.subtract(maxGears.getDiscountPrice()).multiply(BigDecimal.valueOf(order.getCount()));
//                        }
//                        // 需要返现的数量 减去当前订单的购买数量
//                        specBackMp.put(order.getSpecId(), specBackMp.get(order.getSpecId()) - nowByCount);
//                    }
//
//                }
//            } else {
//                /* 无规格团购结算 逻辑 与 有规格基本一样 只是用于计算返现价格的变量不同*/
//                List<MerchantGroupGoodsPrice> merchantGroupGoodsPrices = merchantGroupGoodsPriceService.listForUpdate(new QueryWrapper<MerchantGroupGoodsPrice>()
//                        // 下单的商品id
//                        .eq(MerchantGroupGoodsPrice.GROUP_GOODS_ID, order.getGroupGoodsId())
//                        // 根据完成档位 倒叙
//                        .orderByDesc(MerchantGroupGoodsPrice.SUCCESS_GEAR));
//
//                MerchantGroupGoodsPrice maxGears = null;
//                if (!noSpecMp.containsKey(goods.getId())) {
//
//                    int totalCount = usGroupGoodsOrderService.totalCount(map);
//                    for (MerchantGroupGoodsPrice item : merchantGroupGoodsPrices) {
//                        if (totalCount >= item.getSuccessGear()) {
//                            maxGears = item;
//                            noSpecMp.put(goods.getId(), maxGears);
//                            noSpecBackMp.put(goods.getId(), maxGears.getSuccessGear());
//                            break;
//                        }
//                    }
//                    if (maxGears == null) {
//                        noSpecMp.put(goods.getId(), null);
//                    }
//                } else {
//                    maxGears = specMp.get(goods.getId());
//                }
//
//                Integer nowByCount = order.getCount();
//
//                if (maxGears != null) {
//                    if (nowByCount >= noSpecBackMp.get(goods.getId())) {
//                        noSpecBackMp.put(goods.getId(), 0);
//                    } else {
//                        MerchantGroupGoodsPrice meetGears = null;
//                        for (MerchantGroupGoodsPrice item : merchantGroupGoodsPrices) {
//                            if (nowByCount >= item.getSuccessGear()) {
//                                meetGears = item;
//                                break;
//                            }
//                        }
//                        if (meetGears != null) {
//                            backMoney = meetGears.getDiscountPrice()
//                                    .subtract(maxGears.getDiscountPrice()).multiply(BigDecimal.valueOf(order.getCount()));
//                        } else {
//                            backMoney = goods.getOriginalPrice().subtract(maxGears.getDiscountPrice()).multiply(BigDecimal.valueOf(order.getCount()));
//                        }
//                        noSpecBackMp.put(goods.getId(), noSpecBackMp.get(goods.getId()) - nowByCount);
//                    }
//
//                }
//            }
//
//            /* 如果有返现金额则设置返现*/
//            if (backMoney != null) {
//                // 设置订单返现金额
//                order.setCashBack(backMoney);
//
//                // 得到商家最大能承受的返现额度
//                BigDecimal max = merchantInfo.getBalance().add(merchantInfo.getMargin());
//
//                // 判断当前商家资金是否足以扣款
//                if (max.compareTo(backMoney) >= 0) {
//                    // 需要扣除的余额
//                    BigDecimal balance = null;
//                    // 判断商家余额是否足够返现 不足够的部分从保证金中扣除
//                    if (merchantInfo.getBalance().compareTo(backMoney) < 0) {
//                        // 得到商家余额
//                        balance = merchantInfo.getBalance();
//                        // 需要返现的金额 - 当前余额 剩余返现余额 从保证金中扣除
//                        BigDecimal boot = backMoney.subtract(balance);
//                        // 重设保证金
//                        merchantInfo.setMargin(merchantInfo.getMargin().subtract(boot));
//                        // 添加支出流水
//                        merchantIncomeExpendList.add(new MerchantIncomeExpend()
//                                .setMerchantId(goods.getMerchantId()).setMoney(boot)
//                                .setStatus(-1).setOrderNum(order.getOrderNo()).setRemark("扣除保证金 - 团购商品用户返现"));
//                    } else {
//                        balance = backMoney;
//                    }
//                    // 减去商家需要支付的余额
//                    merchantInfo.setBalance(merchantInfo.getBalance().subtract(balance));
//                    // 添加商家支出流水 大于0表示扣除了商家余额
//                    if (balance.compareTo(new BigDecimal(0)) > 0) {
//                        merchantIncomeExpendList.add(new MerchantIncomeExpend()
//                                .setMerchantId(goods.getMerchantId()).setMoney(balance)
//                                .setStatus(-1).setOrderNum(order.getOrderNo()).setRemark("扣除余额 - 团购商品用户返现"));
//                    }
//
//                    // 给用户返现
//                    usInfo.setBalance(usInfo.getBalance().add(backMoney));
//                    // 添加用户收入流水
//                    usIncomeExpendList.add(new UsIncomeExpend()
//                            .setStatus(1).setMoney(backMoney)
//                            .setOrderNum(order.getOrderNo()).setType(1)
//                            .setRemark("团购商品返现 : " + goods.getTitle())
//                            .setHasFreeze(1).setUsId(usInfo.getId()));
//                } else {
//                    // 欠款订单打备注
//                    order.setRemark("返现失败, 商家余额以及保证金不足 欠款 : " + backMoney);
//                }
//            }
//            // 设置订单状态类型
//            Integer type = order.getType();
//            // 快递 和 配送 设置 待收货
//            if (type == 1 || type == 3) {
//                order.setStatus(1);
//            } else if (type == 0) {
//                // 自提设置待提货
//                order.setStatus(3);
//            }
//            //结果提交(用户收入商家支出订单差价回写)
//            if (!usInfoService.updateById(usInfo)) {
//                throw new ServiceException(usInfo.toString());
//            }
//            if (!merchantInfoService.updateById(merchantInfo)) {
//                throw new ServiceException(merchantInfo.toString());
//            }
//
//            if (usIncomeExpendList.size() > 0 && !usIncomeExpendService.saveBatch(usIncomeExpendList)) {
//                throw new ServiceException(usIncomeExpendList.toString());
//            }
//            if (merchantIncomeExpendList.size() > 0 && !merchantIncomeExpendService.saveBatch(merchantIncomeExpendList)) {
//                throw new ServiceException(merchantIncomeExpendList.toString());
//            }
//            if (!usGroupGoodsOrderService.updateById(order)) {
//                throw new ServiceException(order.toString());
//            }
//
//            if (backMoney != null) {
//                LogUtil.info("↓↓↓↓↓↓ 团购商品订单返现结算 ↓↓↓↓↓");
//                LogUtil.info("商家id : {}", merchantInfo.getId());
//                LogUtil.info("订单号 : {}", order.getOrderNo());
//                LogUtil.info("返现目标用户id : {}", usInfo.getId());
//                LogUtil.info("返现金额 : {}", backMoney);
//                LogUtil.info("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");
//            }
//
//
//        });
//        merchantGroupGoodsRepository.rmTiming(goods.getId());
//        // 判断是否需要重新上架
//        if (goods.getIsAutoShelving() == 1) {
//            Integer shelvingTime = goods.getAutoShelvingTime();
//            if (shelvingTime != null) {
//                Long addTime = Long.parseLong(shelvingTime + "") * 60 * 60;
//                // 得到当前时间
//                LocalDateTime nowTime = LocalDateTime.now(DateFormatTemplate.ZONE_SHANGHAI);
//                // 得到拼团结束时间
//                LocalDateTime endTime = nowTime.plusSeconds(addTime);
//                goods.setStartTime(nowTime.format(DateTimeFormatter.ofPattern(DateFormatTemplate.GROUP_GOODS_WRITE_2)));
//                goods.setEndTime(endTime.format(DateTimeFormatter.ofPattern(DateFormatTemplate.GROUP_GOODS_WRITE_2)));
//                goods.setBatchNum(goods.getBatchNum() + 1);
//                goods.setStatus(0);
//                merchantGroupGoodsRepository.setTiming(goods.getId(),endTime);
//            }
//        }
//        if (!updateById(goods)) {
//            LogUtil.warn("团购结算异常 -> 重设商品信息失败 : {}", goods);
//        }
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void down(List<UsGroupGoodsOrder> list, MerchantGroupGoods merchantGroupGoods) {
        list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(UsGroupGoodsOrder::getUsId))), ArrayList::new));
        merchantGroupGoods.setStatus(-1);
        if (list.size() != 0) {
            //如果有用户，那么发送系统消息和聊天消息
            list.forEach(user -> {
                String key=RedisConfig.KEY_INFO + "CHAT-";
                String content = "很抱歉，由于商家对商品进行下架，该批拼单商品下的所有订单已失效，稍后商家会主动联系您协商退款，如果商家长时间没联系您，请和平台进行反馈";
                //发送系统消息
                SysMessage sysMessage = new SysMessage();
                sysMessage.setTitle("您参与的商品已下架");
                sysMessage.setContent(content);
                sysMessage.setUsId(user.getUsId());
                if (!sysMessageService.save(sysMessage)) {
                    throw new ServiceException();
                }
                //发送聊天消息
                String suffix = user.getUsId() + ":" + merchantGroupGoods.getMerchantId();
                SysChat sysChat = new SysChat();
                sysChat.setSendType(0).setUid(merchantGroupGoods.getMerchantId()).setType("merchant").setMsgType("text").setContent(content).setSendId(user.getUsId())
                        .setSessionId(suffix).setCreateTime(new Date());
                key = key + suffix;
                //先查询redis中是否有商家+用户的对话id键值对存在，如果有，直接那么获取该键值对，往里面添加一条数据，如果没有，那么新建键值对
                if (!redisUtil.hasKey(key)) {
                    //添加新聊天集合
                    List<SysChat> sysChats = new ArrayList<>();
                    sysChats.add(sysChat);
                    redisUtil.set(key, sysChats);
                } else {
                    //追加聊天记录
                    List<SysChat> sysChats = (List<SysChat>) redisUtil.get(key);
                    sysChats.add(sysChat);
                    redisUtil.set(key, sysChats);
                }
                //数据库插入
                if (!sysChatService.save(sysChat)) {
                    throw new ServiceException("插入聊天记录失败");
                }
            });
        }
        if (!updateById(merchantGroupGoods)) {
            throw new ServiceException();
        }

    }

    /**
     * 获取附近团购
     * @param lat 维度
     * @param lng 经度
     * @return 团购对象
     */
    @Override
    public List<GroupGoodsDTO> getNearbyGroupGoods(String lat, String lng) {
        return merchantGroupGoodsMapper.findNearbyGroupGoods(lat, lng);
    }

    /**
     * 根据快照获取价格范围
     * @param jsonString 商品快照
     * @return 返回价格范围(xx-xx)或单个值(xx)
     */
    @Override
    public String getPriceRange(String jsonString) {
        org.json.JSONObject jsonObject = new org.json.JSONObject(jsonString);
        String priceList = jsonObject.getString("priceList");
        org.json.JSONArray products = new org.json.JSONArray(priceList);

        double minProduct = Double.MAX_VALUE;
        double maxProduct = Double.MIN_VALUE;

        for (int i = 0; i < products.length(); i++) {
            org.json.JSONObject product = products.getJSONObject(i);
            // 检查是否存在 priceGear 数组
            if (product.has("priceGear")) {
                org.json.JSONArray priceGears = product.getJSONArray("priceGear");

                for (int j = 0; j < priceGears.length(); j++) {
                    org.json.JSONObject priceGear = priceGears.getJSONObject(j);
                    double discountPrice = priceGear.getDouble("discountPrice");
                    int successGear = priceGear.getInt("successGear");
                    double productValue = discountPrice * successGear;

                    minProduct = Math.min(minProduct, productValue);
                    maxProduct = Math.max(maxProduct, productValue);
                }
            } else { // 直接处理 discountPrice 和 successGear
                double discountPrice = product.getDouble("discountPrice");
                int successGear = product.getInt("successGear");
                double productValue = discountPrice * successGear;

                minProduct = Math.min(minProduct, productValue);
                maxProduct = Math.max(maxProduct, productValue);
            }
        }

        // 当最小值和最大值相等时，只返回一个值
        if (minProduct == maxProduct) {
            return String.valueOf(minProduct);
        } else {
            return minProduct + "-" + maxProduct;
        }
    }

    @Override
    public String getGoodsMainImgById(Long groupGoodsId) {
        return merchantGroupGoodsMapper.getMainImgById(groupGoodsId);
    }
}

